import { ref, reactive } from 'vue'
import { defineStore } from 'pinia'
import type { ApiClient, Identifiable, Pagination, SearchParams } from '../types/api'

export function createBaseStore<T extends Identifiable>(storeName: string, apiClient: ApiClient<T>) {
    return defineStore(storeName, () => {
        // 状态
        const items = ref<T[]>([])
        const currentItem = ref<T | null>(null)
        const loading = ref(false)
        const error = ref<string | null>(null)
        const pagination = reactive<Pagination>({
            page: 1,
            size: 10,
            total: 0,
            pages: 0,
        })

        const searchParams = reactive<SearchParams>({})

        // 通用的异步处理函数
        const handleAsync = async (fn: () => Promise<any>) => {
            loading.value = true
            try {
                return await fn()
            } catch (err) {
                console.error('操作失败:', err)
                error.value = '操作失败'
                throw err
            } finally {
                loading.value = false
            }
        }

        const fetchItems = () =>
            handleAsync(async () => {
                const result = await apiClient.findAll({
                    page: pagination.page,
                    size: pagination.size,
                    ...searchParams,
                })
                items.value = result.items
                Object.assign(pagination, result.pagination)
            })

        const fetchItem = (id: number) =>
            handleAsync(async () => {
                const item = await apiClient.findById(id)
                currentItem.value = item
                return item
            })

        const createItem = (data: T) =>
            handleAsync(async () => {
                const newItem = await apiClient.create(data)
                await fetchItems()
                return newItem
            })

        const updateItem = (data: T) =>
            handleAsync(async () => {
                if ((data as any).id === undefined) {
                    throw new Error('更新失败：缺少 ID')
                }
                const updatedItem = await apiClient.update(data)
                await fetchItems()
                return updatedItem
            })

        const deleteItem = (id: number) =>
            handleAsync(async () => {
                await apiClient.delete(id)
                await fetchItems()
            })

        const updateSearchParams = (params: SearchParams) => {
            Object.assign(searchParams, params)
            pagination.page = 1
        }

        const updatePagination = (newPagination: Pagination) => {
            Object.assign(pagination, newPagination)
        }

        return {
            items,
            currentItem,
            loading,
            error,
            pagination,
            searchParams,
            fetchItems,
            fetchItem,
            createItem,
            updateItem,
            deleteItem,
            updateSearchParams,
            updatePagination,
        }
    })
}